package ru.space.academy.service;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import ru.space.academy.dto.JWTResponseDTO;
import ru.space.academy.dto.UserAuthDTO;
import ru.space.academy.dto.UserRegistrationDTO;
import ru.space.academy.exception.IncorrectInputDataException;
import ru.space.academy.model.Student;
import ru.space.academy.repository.UserRepository;

@Service
public class AuthService {

    private final JWTService jwtService;
    private final UserService userService;
    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;
    private final AuthenticationManager authenticationManager;

    public AuthService(JWTService jwtService, UserService userService, UserRepository userRepository,
                       PasswordEncoder passwordEncoder, AuthenticationManager authenticationManager) {
        this.jwtService = jwtService;
        this.userService = userService;
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
        this.authenticationManager = authenticationManager;
    }

    public void registerUser(UserRegistrationDTO regDTO) {
        if (!regDTO.getPassword().equals(regDTO.getDoublePassword())) {
            throw new IncorrectInputDataException("Введеные Вами пароли отличаются!");
        }
        if (userRepository.existsByLogin(regDTO.getLogin())) {
            throw new IncorrectInputDataException("Введеный Вами логин уже занят!");
        }
        var user = new Student();
        user.setLogin(regDTO.getLogin());
        user.setName(regDTO.getName());
        user.setLastName(regDTO.getLastName());
        user.setPatronymic(regDTO.getPatronymic());
        user.setBirthDate(regDTO.getBirthDate());
        user.setRole(regDTO.getRole());
        user.setActive(true);
        user.setPassword(passwordEncoder.encode(regDTO.getPassword()));

        userRepository.save(user);
    }

    /**
     * Аутентификация пользователя
     *
     * @param authDTO данные пользователя
     * @return токен
     */
    public JWTResponseDTO auth(UserAuthDTO authDTO) {
        authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(
                authDTO.getLogin(),
                authDTO.getPassword()
        ));

        var user = userService
                .userDetailsService()
                .loadUserByUsername(authDTO.getLogin());

        var jwt = jwtService.generateToken(user);
        return new JWTResponseDTO(jwt);
    }
}